From dab3d2969db5dca7011c185af76b188b21e08e44 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 23 Oct 2005 16:54:51 +0100 Subject: [PATCH] Enable TSC-offsetting capability to ensure that VMX guest's TSC remains in sync with virtual-PIT interrupts. This avoids the following message from full-virt Linux: "Losing too many ticks! TSC cannot be used as a timesource. =20 Possible reasons for this are: You're running with Speedstep, ......" Signed-off-by: Eddie Dong Signed-off-by: Edwin Zhai --- xen/arch/x86/vmx_intercept.c | 2 ++ xen/arch/x86/vmx_io.c | 8 ++++++++ xen/include/asm-x86/vmx.h | 1 + xen/include/asm-x86/vmx_virpit.h | 1 + xen/include/asm-x86/vmx_vmcs.h | 1 + 5 files changed, 13 insertions(+) diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 4e9a1fe86d..0a3c168107 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -254,6 +254,8 @@ void vmx_hooks_assist(struct vcpu *v) vpit->init_val); vpit->period = 1000000; } + vpit->period_cycles = (u64)vpit->period * cpu_khz / 1000000L; + printk("VMX_PIT: guest freq in cycles=%lld\n",(long long)vpit->period_cycles); vpit->channel = ((p->u.data >> 24) & 0x3); vpit->first_injected = 0; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 434d302209..4ede995d8c 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -799,6 +799,7 @@ static inline void interrupt_post_injection(struct vcpu * v, int vector, int type) { struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); + u64 drift; switch(type) { @@ -812,6 +813,13 @@ interrupt_post_injection(struct vcpu * v, int vector, int type) vpit->pending_intr_nr--; } vpit->inject_point = NOW(); + drift = vpit->period_cycles * vpit->pending_intr_nr; + drift = v->arch.arch_vmx.tsc_offset - drift; + __vmwrite(TSC_OFFSET, drift); + +#if defined (__i386__) + __vmwrite(TSC_OFFSET_HIGH, (drift >> 32)); +#endif } break; diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index d16080cb1a..445c24bb59 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -65,6 +65,7 @@ extern unsigned int cpu_rev; CPU_BASED_MWAIT_EXITING | \ CPU_BASED_MOV_DR_EXITING | \ CPU_BASED_ACTIVATE_IO_BITMAP | \ + CPU_BASED_USE_TSC_OFFSETING | \ CPU_BASED_UNCOND_IO_EXITING \ ) diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index d0c758dd37..9539682d94 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -19,6 +19,7 @@ struct vmx_virpit { /* for simulation of counter 0 in mode 2*/ u32 period; /* pit frequency in ns */ + u64 period_cycles; /* pit frequency in cpu cycles */ s_time_t scheduled; /* scheduled timer interrupt */ unsigned int channel; /* the pit channel, counter 0~2 */ unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index f47daf8e09..207289a59d 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -96,6 +96,7 @@ struct arch_vmx_struct { struct msr_state msr_content; struct mmio_op mmio_op; /* MMIO */ void *io_bitmap_a, *io_bitmap_b; + u64 tsc_offset; }; #define vmx_schedule_tail(next) \ -- 2.30.2